package com.upay.android.controller.fragment;

import static com.upay.android.controller.helper.Results.*;

import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.type.TypeReference;

import android.app.LoaderManager.LoaderCallbacks;
import android.content.Loader;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

import com.upay.android.R;
import com.upay.android.controller.helper.Keys;
import com.upay.android.controller.validation.EmailValidator;
import com.upay.android.controller.validation.PasswordValidator;
import com.upay.android.core.service.RestService;
import com.upay.android.domain.account.UserAccount;
import com.upay.android.domain.authentication.AuthenticationToken;
import com.upay.android.domain.request.RequestBody;
import com.upay.android.domain.request.RequestEnvelope;
import com.upay.android.domain.request.RequestHeader;
import com.upay.android.domain.response.ResponseEnvelope;
import com.upay.android.domain.rest.RestRequest;
import com.upay.android.domain.user.User;
import com.upay.android.util.StringUtils;
import com.upay.android.util.rest.UrlHelper;

public class CreateAccountFragment extends AbstractFragment implements LoaderCallbacks<ResponseEnvelope<AuthenticationToken>>{

	/* ---- Constants ---- */
	public final static int CREATE_ACCOUNT = 0;
	
	/* ---- Instance Variables ---- */

	private EmailValidator mEmailValidator = null;
	private PasswordValidator mPasswordValidator = null;
	
	private EditText mUserIdField = null;
	private EditText mPasswordField = null;
	private EditText mFirstNameField = null;
	private EditText mLastNameField = null;
	private Button mCreateButton = null;
	
	/* ---- Constructors ---- */

	/* ---- Business Methods ---- */

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getContext().setTitle(R.string.create_account_fragment_title);
		setHasOptionsMenu(true);
		mEmailValidator = new EmailValidator();
		mPasswordValidator = new PasswordValidator();

	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_create_account, parent, false);
        mUserIdField = (EditText)view.findViewById(R.id.value_create_account_userid);
        mPasswordField = (EditText)view.findViewById(R.id.value_create_account_password);
        mFirstNameField = (EditText)view.findViewById(R.id.value_create_account_firstname);
        mLastNameField = (EditText)view.findViewById(R.id.value_create_account_lastname);
        mCreateButton = (Button)view.findViewById(R.id.button_create_account);
  
        mCreateButton.setOnClickListener(new View.OnClickListener() {		
			@Override
			public void onClick(View view) {
		    	
				// Retrieve credentials
		        String userId = mUserIdField.getText().toString();
		        String password = mPasswordField.getText().toString();
		        String firstName = mFirstNameField.getText().toString();
		        String lastName = mLastNameField.getText().toString();

		        // Validate credentials
		        Map<String, String> errors = new HashMap<String, String>();
		        mEmailValidator.validate(userId, errors);
		        mPasswordValidator.validate(password, errors);
		        
		        if (!StringUtils.hasText(firstName)) {
		        	errors.put(Keys.HAS_TEXT_VALIDATION, "Firstname is mandatory");
		        }
		        
		        if (!StringUtils.hasText(lastName)) {
		        	errors.put(Keys.HAS_TEXT_VALIDATION, "Lstname is mandatory");
		        }
		        
		        
		        if (errors.size() > 0) {
		        	getContext().showValidationErrors(
		        		getContext().getApplicationContext().getResources().getString(R.string.create_account_invalid_credentials),
		        		Gravity.BOTTOM);
		        } else  {       	
	           	    Bundle bundle = new Bundle();
	           	    bundle.putString(Keys.USERID, userId);
	           	    bundle.putString(Keys.PASSWORD, password);
	           	    bundle.putString(Keys.FIRSTNAME, firstName);
	           	    bundle.putString(Keys.LASTNAME, lastName);
	           	    getLoaderManager().initLoader(CREATE_ACCOUNT, bundle, CreateAccountFragment.this);
		        }
			}
		});
		
		return view;
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		inflater.inflate(R.menu.create_account_menu, menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.action_create_account_cancel:
			getFragmentManager().popBackStack();
		}
		return true;
	}
	
	/* ---- Interfaces ---- */
	
	@Override
	public Loader<ResponseEnvelope<AuthenticationToken>> onCreateLoader(int id, Bundle bundle) {
		
		User user = new User(
				bundle.getString(Keys.USERID),
				bundle.getString(Keys.FIRSTNAME),
				bundle.getString(Keys.LASTNAME));
		UserAccount account = new UserAccount(
				bundle.getString(Keys.USERID), 
				bundle.getString(Keys.PASSWORD),
				user);
		
		RequestEnvelope<RequestHeader, UserAccount> requestEnvelope = new RequestEnvelope<RequestHeader, UserAccount>(
			new RequestHeader(),
			new RequestBody<UserAccount>(account));
		TypeReference<ResponseEnvelope<AuthenticationToken>> typeReference = new TypeReference<ResponseEnvelope<AuthenticationToken>>() {};
		RestRequest<RequestHeader, UserAccount, AuthenticationToken> restRequest = 
			new RestRequest<RequestHeader, UserAccount, AuthenticationToken>(
				UrlHelper.getUrl(getResources(), UrlHelper.CREATE_ACCOUNT),
				requestEnvelope,
				typeReference);           	    
		RestService<RequestHeader, UserAccount, AuthenticationToken> restService = 
		   	new RestService<RequestHeader, UserAccount, AuthenticationToken>(
		   		getActivity().getApplicationContext(),
		   		restRequest);
		return restService;	   	    
	}

	@Override
	public void onLoadFinished(Loader<ResponseEnvelope<AuthenticationToken>> loader, ResponseEnvelope<AuthenticationToken> responseEnvelope) {
		if (!responseEnvelope.getResponseHeader().getStatus()) {
			getContext().handleError(responseEnvelope.getResponseBody().getResponseError());
		} else {
			// Return to Activity
			getContext().setResult(ACCOUNT_CREATED, getContext().getIntent());
			getContext().finish();
		}

	}

	@Override
	public void onLoaderReset(Loader<ResponseEnvelope<AuthenticationToken>> arg0) {
	}

	/* ---- Interfaces ---- */

	
	/* ---- Getters and Setters ---- */

	public EditText getmUserIdField() {
		return mUserIdField;
	}

	public void setmUserIdField(EditText mUserIdField) {
		this.mUserIdField = mUserIdField;
	}

	public EditText getmPasswordField() {
		return mPasswordField;
	}

	public void setmPasswordField(EditText mPasswordField) {
		this.mPasswordField = mPasswordField;
	}

	public EditText getmFirstNameField() {
		return mFirstNameField;
	}

	public void setmFirstNameField(EditText mFirstNameField) {
		this.mFirstNameField = mFirstNameField;
	}

	public EditText getmLastNameField() {
		return mLastNameField;
	}

	public void setmLastNameField(EditText mLastNameField) {
		this.mLastNameField = mLastNameField;
	}


}
